//TODO: How to handle and report exceptions for batch apex??
//TODO: Replace Filter criteria with a picklist value enumerator retreived fom Schema - instead of hardcoded string.

global class UpdateAccountFields implements Database.Batchable<sObject> {


	//NOTE: Had to select all fields used in CO Formual field, otherwise the values in the CO field were not extracted 
	//this is SFDC Bug as of 12/09/2009
	final String query = 'Select Id, Name, IM_Enterprise_Account_Manager__c, IM_Enterprise_Account_Manager_FORMULA__c, ' + 
							'Parent.IM_Enterprise_Account_Manager__c, ' +
							'Parent.Parent.IM_Enterprise_Account_Manager__c, ' +
							'Parent.Parent.Parent.IM_Enterprise_Account_Manager__c, ' +
							'Parent.Parent.Parent.Parent.IM_Enterprise_Account_Manager__c, ' +
							'Parent.Parent.Parent.Parent.Parent.IM_Enterprise_Account_Manager__c ' +
						  'From Account where IM_Hierarchy_Level__c != \'Book of Business/IMGA\' AND Name LIKE \'%Andrey%\'';
	
	Schema.sObjectField toField = Schema.Account.IM_Enterprise_Account_Manager__c;
	Schema.sObjectField fromField = Schema.Account.IM_Enterprise_Account_Manager_FORMULA__c;
	
	Schema.DisplayType toFieldType = toField.getDescribe().getType();	

	String fromFieldName = fromField.getDescribe().getName();
	String toFieldName = toField.getDescribe().getName();
	
	
	global Database.QueryLocator start(Database.BatchableContext BC){
		System.debug('============== inside start method ========================');
    	return Database.getQueryLocator(query);
	}


	
	global void execute(Database.BatchableContext BC, List<sObject> scope){
		System.debug('============== inside execute method ========================');
		
   		for(sObject sObj : scope){
   			
   			System.debug('-------------- sObject before update: ' + sObj);
			System.debug('-------------- toField type: ' + toFieldType);
				
				
			String fromFieldValue = null;
			String toFieldValue = null;
				
			fromFieldValue = String.valueOf(sObj.get(fromFieldName));
			toFieldValue = String.valueOf(sObj.get(toFieldName));
			
				//if target field id reference (type Id) and is not null - truncate from 18 to 15 characters
				if (toFieldType == Schema.DisplayType.REFERENCE) {
					System.debug('-----------  inside if - truncating REFERENCE field to 15 chars ---------------- ');
					toFieldValue = (toFieldValue == null) ? null : toFieldValue.substring(0, 15);
				}
			
			System.debug('-------------- ' + toFieldName + ': ' + toFieldValue);
			System.debug('-------------- ' + fromFieldName + ': ' + fromFieldValue);
			
			
      		if(toFieldValue != fromFieldValue){ 
      			System.debug('-----------  inside if - updating EAM field ---------------- ');
      			sObj.put(toFieldName,  fromFieldValue);
      		}
   		}      
      	update scope;
	}

	
	
	global void finish(Database.BatchableContext BC){
		System.debug('============== inside finish method ========================');
	}
}